/*
 * PWM.cpp
 *
 * Created: 2012-05-16 09:50:21
 *  Author: Johan
 */ 
#include "PWM.h"
	
PWM::PWM() {
	
	min = 400;
	max = 2200;
	period = 20;
	direction = 20;
	
	//Enable OC3A,B,C
	DDRE |= (1<<PE3)|(1<<PE4)|(1<<PE5);
			
	//Mode 10 page 138
	//PWM, Phase Correct
	TCCR3A = (1<<COM3A1)|(0<<COM3A0)|(1<<COM3B1)|(0<<COM3B0)|(1<<COM3C1)|(0<<COM3C0)|(1<<WGM31)|(0<<WGM30);
	TCCR3B = (1<<WGM33)|(0<<WGM32)|(0<<CS32)|(1<<CS31)|(0<<CS30); //Prescaler
			
	//TOP Value
	ICR3 = 20000;
	//Duty cycle
	OCR3A = 0;
	OCR3B = 0;
	OCR3C = 0;
}
	
void PWM::setWidth(Channel c, int value){
	switch(c){
		case A:
		OCR3A = value;
		break;
		case B:
		OCR3B = value;
		break;
		case C:
		OCR3C = value;
		break;
		default:
		break;
	}
}
	
int PWM::getWidth(Channel c){
	switch(c){
		case A:
		return OCR3A;
		break;
		case B:
		return OCR3B;
		break;
		case C:
		return OCR3C;
		break;
		default:
		break;
	}
}
	
float PWM::getDutycycle(Channel c) {
	
	switch(c){
		case A:
		return OCR3A/ICR3;
		break;
		case B:
		return OCR3B/ICR3;
		break;
		case C:
		return OCR3C/ICR3;
		break;
		default:
		break;
	}
}
	
void PWM::setDutycycle(Channel c, float duty_cycle) {
	
	setWidth(c, ICR3*duty_cycle);
	
}

void PWM::enableCompareInterrupt(Channel c) {
	switch(c){
		case A:
		TIMSK3 |= (1<<OCIE3A);
		break;
		case B:
		TIMSK3 |= (1<<OCIE3B);
		break;
		case C:
		TIMSK3 |= (1<<OCIE3C);
		break;
		default:
		break;
	}
}
	
void PWM::disableCompareInterrupt(Channel c) {
	switch(c) {
		case A:
		TIMSK3 &= ~(1<<OCIE3A);
		break;
		case B:
		TIMSK3 &= ~(1<<OCIE3B);
		break;
		case C:
		TIMSK3 &= ~(1<<OCIE3C);
		break;
		default:
		break;
	}
}
